/*
 * input.c
 *
 *  Created on: 03/11/2012
 *      Author: julian
 */

#include <stdio.h>
#include <stdlib.h>

#include "packet_input.h"
#include "app.h"

static xbee_RxFrame64_t packet64;
static xbee_RxFrame16_t packet16;
static xbee_AtRemoteResponse_t at_remoteresponse;
static xbee_TxStatus_t tx_response;
static xbee_AtCommandResponse_t atresponse;

static union {
    uint8_t c[8];
    uint64_t a;
} addr64;
int i = 0;

static void print_rbuf(struct rx_frame *rbuf) {
    printf("\nr_frame len: %d, api: 0x%X,  ", rbuf->length, rbuf->api_id);
    printf("\ndata: ");
    for (i = 0; i < rbuf->length - 1; ++i) {
        printf("%X ", rbuf->data[i]);
    }
}

void packetInput(struct rx_frame *rbuf) {

    if (rbuf == NULL) {
#ifdef INPUT_DEBUG
        printf("\n...");
#endif
        return;
    } else {
        switch (rbuf->api_id) {
            case RX_16_RESPONSE: {
                packet16.dataSize = rbuf->length - 5;
                packet16.sourceAddress = (rbuf->data[0] | rbuf->data[1]) & 0xff;
                packet16.RSSI = rbuf->data[2];
                packet16.options = rbuf->data[3];
                packet16.data = (uint8_t*) malloc(
                        packet16.dataSize * sizeof(uint8_t));
                for (i = 0; i < packet16.dataSize; i++) {
                    packet16.data[i] = rbuf->data[4 + i];
                }
#ifdef INPUT_DEBUG
                print_rx_16(packet16);
#endif

                appLayerInput(rbuf->api_id, (xbee_RxFrame16_t*) &packet16);
                //-------------------------------------------------------------------
                break;
            }
            case RX_64_RESPONSE: {
                packet64.dataSize = rbuf->length - 11;
                for (i = 0; i < 8; i++) {
                    addr64.c[7 - i] = rbuf->data[i];
                }
                packet64.sourceAddress = addr64.a;
                packet64.RSSI = rbuf->data[8];
                packet64.options = rbuf->data[9];
                packet64.data = (uint8_t*) malloc(
                        packet64.dataSize * sizeof(uint8_t));
                for (i = 0; i < packet64.dataSize; i++) {
                    packet64.data[i] = rbuf->data[10 + i];
                }
#ifdef INPUT_DEBUG
                print_rx_64(packet64);
#endif
                //print_rbuf(rbuf);

                appLayerInput(rbuf->api_id, (xbee_RxFrame64_t*) &packet64);
                //----------------------------------------------------------------------

                break;
            }
            case AT_COMMAND_RESPONSE: {
                atresponse.frameId = rbuf->data[0];
                atresponse.command[0] = (char) rbuf->data[1];
                atresponse.command[1] = (char) rbuf->data[2];
                atresponse.status = rbuf->data[3];
                atresponse.valueSize = rbuf->length - 5;
                for (i = 0; i < atresponse.valueSize; i++) {
                    atresponse.value[i] = rbuf->data[4 + i];
                }
                //print_rbuf(rbuf);
#ifdef INPUT_DEBUG
                print_AT_response(atresponse);
#endif
                appLayerInput(AT_COMMAND_RESPONSE,
                        (xbee_AtCommandResponse_t*) &atresponse);
                break;
            }
            case AT_REMOTE_RESPONSE: {

                at_remoteresponse.frameId = rbuf->data[0];
                for (i = 0; i < 8; i++) {
                    addr64.c[7 - i] = rbuf->data[i + 1];
                }
                at_remoteresponse.sourceAddress64 = addr64.a;
                at_remoteresponse.sourceAddress16 = (rbuf->data[9] | rbuf->data[10])
                        & 0xff;
                at_remoteresponse.command[0] = (char) rbuf->data[11];
                at_remoteresponse.command[1] = (char) rbuf->data[12];
                at_remoteresponse.status = rbuf->data[13];
                at_remoteresponse.valueSize = (rbuf->length) - 15;
                for (i = 0; i < at_remoteresponse.valueSize; i++) {
                    at_remoteresponse.value[i] = rbuf->data[14 + i];
                }
#ifdef INPUT_DEBUG
                print_AT_remote_response(at_remoteresponse);
#endif
                //print_rbuf(rbuf);
                appLayerInput(rbuf->api_id,
                        (xbee_AtRemoteResponse_t*) &at_remoteresponse);

                break;
            }

            case TX_STATUS_RESPONSE: {
                tx_response.frameId = rbuf->data[0];
                tx_response.status = rbuf->data[1];

                //print_rbuf(rbuf);
#ifdef INPUT_DEBUG
                print_tx_status(tx_response);
#endif
                appLayerInput(rbuf->api_id, (xbee_TxStatus_t*) &tx_response);

                break;
            }
            default: {
                return;
                break;
            }
        }
    }
}

